<?php
/**
 *
 * @author 孙春雷
 *        
 */
class Service_Inventory {
	
	// 计划任务执行时间
	const plan_time = '00:00:00';

	public function balances($starttime, $endtime, $sku = NULL)
	{
		// 获取月期初时间
		$opening_time = date_format( date_create( $starttime ), 'Y-m-01' );
		
		// 获取期初库存
		$inventory = new Model_Inventories();
		$opening = $inventory->getCountAndCost( $opening_time, $sku );
		
		// 获取月期初到开始时间的结存
		$in_out = $this->get_in_and_out( $opening_time . ' ' . self::plan_time, $starttime  . ' ' . self::plan_time, $sku );
		$current_in = $in_out ['current_in'];
		$current_out = $in_out ['current_out'];
		$result = $this->calculate( $opening, $current_in, $current_out );
		$opening = $result ['closing'];
		
		// 统计开始时间到结束时间的库存报表
		$in_out = $this->get_in_and_out( $starttime, $endtime, $sku );
		$current_in = $in_out ['current_in'];
		$current_out = $in_out ['current_out'];
		$result = $this->calculate( $opening, $current_in, $current_out );
		
		return $result;
	}

	protected function get_in_and_out($starttime, $endtime, $sku = NULL)
	{
		// 定义最终结果数组
		$result = array ();
		
		// 获取本月入库总的数量和成本
		$warehosue = new Model_Warehouseorders();
		$current_in = $warehosue->getCountAndCost( $starttime, $endtime, $sku );
		
		// 获取本月出库总的数量和成本
		$delivery = new Model_Deliveryorders();
		$current_out = $delivery->getCountAndCost( $starttime, $endtime, $sku );
		
		// 结果合并
		$result ['current_in'] = $current_in;
		$result ['current_out'] = $current_out;
		
		return $result;
	}

	/**
	 * 根据期初和本期入和本期出的库存计算出本期出的成本和期末的数量和成本
	 * 数组参数的键都是sku值
	 *
	 * @param array $opening        	
	 * @param array $current_in        	
	 * @param array $current_out        	
	 * @return multitype:number Ambigous <multitype:, number>
	 */
	protected function calculate(array $opening, array $current_in, array $current_out)
	{
		ini_set('memory_limit', '300M');
		// 定义最终结果数组
		$result = array ();
		// 定义期末库存的数量和成本
		$closing = array ();
		// 获取有入库但是没有期初的sku集合
		$new_ins = array_diff_key( $current_in, $opening );

		foreach ( $new_ins as $key => $value )
		{
			// 期初sku库存数量和成本为0
			$opening [$key] ['count'] = 0;
			$opening [$key] ['cost'] = 0;
		}
		
		foreach ( $opening as $key => $value )
		{
			// 如果sku没有入库记录，本期入的的数量和成本全为0
			if (!array_key_exists( $key, $current_in ))
			{
				$current_in [$key] ['count'] = 0;
				$current_in [$key] ['cost'] = 0;
			}
			// 如果sku没有出库数量，本期出的数量为0
			if (!array_key_exists( $key, $current_out ))
			{
				$current_out [$key] ['count'] = 0;
			}
			// 计算sku本期出的成本,=(期初成本+本期入成本)/（期初数量+本期入数量）*本期出数量
			if (($opening [$key] ['count'] + $current_in [$key] ['count']) == 0)
			{
				$current_out [$key] ['cost'] = 0;
			}
			else
			{		
				$current_out [$key] ['cost'] = round((($opening [$key] ['cost'] + $current_in [$key] ['cost']) / ($opening [$key] ['count'] + $current_in [$key] ['count']) * $current_out [$key] ['count']),2);
			}
			// 计算sku期末的数量和成本，数量=期初数量+本期入的数量-本期出的数量，成本=期初成本+本期入的成本-本期出的成本
			$closing [$key] ['count'] = $opening [$key] ['count'] + $current_in [$key] ['count'] - $current_out [$key] ['count'];
			$closing [$key] ['cost'] = round(($opening [$key] ['cost'] + $current_in [$key] ['cost'] - $current_out [$key] ['cost']),2);
		}
		// 结果合并
		$result ['opening'] = $opening;
		unset($opening);
		$result ['current_in'] = $current_in;
		unset($current_in);
		$result ['current_out'] = $current_out;
		unset($current_out);
		$result ['closing'] = $closing;
		unset($closing);
		return $result;
	}
}
